home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / r_image.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-18  |  37.3 KB  |  1,657 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. #include "r_local.h"
  22. #include <GL/glu.h>
  23.  
  24. image_t        gltextures[MAX_GLTEXTURES];
  25. int            numgltextures;
  26. int            base_textureid;        // gltextures[i] = base_textureid+i
  27.  
  28. static byte             intensitytable[256];
  29. static unsigned char gammatable[256];
  30.  
  31. cvar_t        *intensity;
  32.  
  33. unsigned    d_8to24table[256];
  34.  
  35. qboolean GL_Upload8 (byte *data, int width, int height,  qboolean mipmap, qboolean is_sky );
  36. qboolean GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap);
  37.  
  38.  
  39. int        gl_solid_format = 3;
  40. int        gl_alpha_format = 4;
  41.  
  42. int        gl_tex_solid_format = 3;
  43. int        gl_tex_alpha_format = 4;
  44.  
  45. int        gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
  46. int        gl_filter_max = GL_LINEAR;
  47.  
  48. void GL_SetTexturePalette( unsigned palette[256] )
  49. {
  50.     int i;
  51.     unsigned char temptable[768];
  52.  
  53.     if ( qglColorTableEXT && gl_ext_palettedtexture->value )
  54.     {
  55.         for ( i = 0; i < 256; i++ )
  56.         {
  57.             temptable[i*3+0] = ( palette[i] >> 0 ) & 0xff;
  58.             temptable[i*3+1] = ( palette[i] >> 8 ) & 0xff;
  59.             temptable[i*3+2] = ( palette[i] >> 16 ) & 0xff;
  60.         }
  61.  
  62.         qglColorTableEXT( GL_SHARED_TEXTURE_PALETTE_EXT,
  63.                            GL_RGB,
  64.                            256,
  65.                            GL_RGB,
  66.                            GL_UNSIGNED_BYTE,
  67.                            temptable );
  68.     }
  69. }
  70.  
  71. void GL_EnableMultitexture( qboolean enable )
  72. {
  73.     if ( !qglSelectTextureSGIS && !qglActiveTextureARB )
  74.         return;
  75.  
  76.     if ( enable )
  77.     {
  78.         GL_SelectTexture( GL_TEXTURE1 );
  79.         qglEnable( GL_TEXTURE_2D );
  80.         GL_TexEnv( GL_REPLACE );
  81.     }
  82.     else
  83.     {
  84.         GL_SelectTexture( GL_TEXTURE1 );
  85.         qglDisable( GL_TEXTURE_2D );
  86.         GL_TexEnv( GL_REPLACE );
  87.     }
  88.     GL_SelectTexture( GL_TEXTURE0 );
  89.     GL_TexEnv( GL_REPLACE );
  90. }
  91.  
  92. void GL_SelectTexture( GLenum texture )
  93. {
  94.     int tmu;
  95.  
  96.     if ( !qglSelectTextureSGIS && !qglActiveTextureARB )
  97.         return;
  98.  
  99.     if ( texture == GL_TEXTURE0 )
  100.     {
  101.         tmu = 0;
  102.     }
  103.     else
  104.     {
  105.         tmu = 1;
  106.     }
  107.  
  108.     if ( tmu == gl_state.currenttmu )
  109.     {
  110.         return;
  111.     }
  112.  
  113.     gl_state.currenttmu = tmu;
  114.  
  115.     if ( qglSelectTextureSGIS )
  116.     {
  117.         qglSelectTextureSGIS( texture );
  118.     }
  119.     else if ( qglActiveTextureARB )
  120.     {
  121.         qglActiveTextureARB( texture );
  122.         qglClientActiveTextureARB( texture );
  123.     }
  124. }
  125.  
  126. void GL_TexEnv( GLenum mode )
  127. {
  128.     static int lastmodes[2] = { -1, -1 };
  129.  
  130.     if ( mode != lastmodes[gl_state.currenttmu] )
  131.     {
  132.         qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode );
  133.         lastmodes[gl_state.currenttmu] = mode;
  134.     }
  135. }
  136.  
  137. void GL_Bind (int texnum)
  138. {
  139.     extern    image_t    *draw_chars;
  140.  
  141.     if (gl_nobind->value && draw_chars)        // performance evaluation option
  142.         texnum = draw_chars->texnum;
  143.     if ( gl_state.currenttextures[gl_state.currenttmu] == texnum)
  144.         return;
  145.     gl_state.currenttextures[gl_state.currenttmu] = texnum;
  146.     qglBindTexture (GL_TEXTURE_2D, texnum);
  147. }
  148.  
  149. void GL_MBind( GLenum target, int texnum )
  150. {
  151.     GL_SelectTexture( target );
  152.     if ( target == GL_TEXTURE0 )
  153.     {
  154.         if ( gl_state.currenttextures[0] == texnum )
  155.             return;
  156.     }
  157.     else
  158.     {
  159.         if ( gl_state.currenttextures[1] == texnum )
  160.             return;
  161.     }
  162.     GL_Bind( texnum );
  163. }
  164.  
  165. typedef struct
  166. {
  167.     char *name;
  168.     int    minimize, maximize;
  169. } glmode_t;
  170.  
  171. glmode_t modes[] = {
  172.     {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
  173.     {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
  174.     {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
  175.     {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
  176.     {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
  177.     {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
  178. };
  179.  
  180. #define NUM_GL_MODES (sizeof(modes) / sizeof (glmode_t))
  181.  
  182. typedef struct
  183. {
  184.     char *name;
  185.     int mode;
  186. } gltmode_t;
  187.  
  188. gltmode_t gl_alpha_modes[] = {
  189.     {"default", 4},
  190.     {"GL_RGBA", GL_RGBA},
  191.     {"GL_RGBA8", GL_RGBA8},
  192.     {"GL_RGB5_A1", GL_RGB5_A1},
  193.     {"GL_RGBA4", GL_RGBA4},
  194.     {"GL_RGBA2", GL_RGBA2},
  195. };
  196.  
  197. #define NUM_GL_ALPHA_MODES (sizeof(gl_alpha_modes) / sizeof (gltmode_t))
  198.  
  199. gltmode_t gl_solid_modes[] = {
  200.     {"default", 3},
  201.     {"GL_RGB", GL_RGB},
  202.     {"GL_RGB8", GL_RGB8},
  203.     {"GL_RGB5", GL_RGB5},
  204.     {"GL_RGB4", GL_RGB4},
  205.     {"GL_R3_G3_B2", GL_R3_G3_B2},
  206. #ifdef GL_RGB2_EXT
  207.     {"GL_RGB2", GL_RGB2_EXT},
  208. #endif
  209. };
  210.  
  211. #define NUM_GL_SOLID_MODES (sizeof(gl_solid_modes) / sizeof (gltmode_t))
  212.  
  213. /*
  214. ===============
  215. GL_TextureMode
  216. ===============
  217. */
  218. void GL_TextureMode( char *string )
  219. {
  220.     int        i;
  221.     image_t    *glt;
  222.  
  223.     for (i=0 ; i< NUM_GL_MODES ; i++)
  224.     {
  225.         if ( !Q_stricmp( modes[i].name, string ) )
  226.             break;
  227.     }
  228.  
  229.     if (i == NUM_GL_MODES)
  230.     {
  231.         Com_Printf ("bad filter name\n");
  232.         return;
  233.     }
  234.  
  235.     gl_filter_min = modes[i].minimize;
  236.     gl_filter_max = modes[i].maximize;
  237.  
  238.     // change all the existing mipmap texture objects
  239.     for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  240.     {
  241.         if (glt->type != it_pic && glt->type != it_sky )
  242.         {
  243.             GL_Bind (glt->texnum);
  244.             qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  245.             qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  246.         }
  247.     }
  248. }
  249.  
  250. /*
  251. ===============
  252. GL_TextureAlphaMode
  253. ===============
  254. */
  255. void GL_TextureAlphaMode( char *string )
  256. {
  257.     int        i;
  258.  
  259.     for (i=0 ; i< NUM_GL_ALPHA_MODES ; i++)
  260.     {
  261.         if ( !Q_stricmp( gl_alpha_modes[i].name, string ) )
  262.             break;
  263.     }
  264.  
  265.     if (i == NUM_GL_ALPHA_MODES)
  266.     {
  267.         Com_Printf ("bad alpha texture mode name\n");
  268.         return;
  269.     }
  270.  
  271.     gl_tex_alpha_format = gl_alpha_modes[i].mode;
  272. }
  273.  
  274. /*
  275. ===============
  276. GL_TextureSolidMode
  277. ===============
  278. */
  279. void GL_TextureSolidMode( char *string )
  280. {
  281.     int        i;
  282.  
  283.     for (i=0 ; i< NUM_GL_SOLID_MODES ; i++)
  284.     {
  285.         if ( !Q_stricmp( gl_solid_modes[i].name, string ) )
  286.             break;
  287.     }
  288.  
  289.     if (i == NUM_GL_SOLID_MODES)
  290.     {
  291.         Com_Printf ("bad solid texture mode name\n");
  292.         return;
  293.     }
  294.  
  295.     gl_tex_solid_format = gl_solid_modes[i].mode;
  296. }
  297.  
  298. /*
  299. ===============
  300. GL_ImageList_f
  301. ===============
  302. */
  303. void    GL_ImageList_f (void)
  304. {
  305.     int        i;
  306.     image_t    *image;
  307.     int        texels;
  308.     const char *palstrings[2] =
  309.     {
  310.         "RGB",
  311.         "PAL"
  312.     };
  313.  
  314.     Com_Printf ("------------------\n");
  315.     texels = 0;
  316.  
  317.     for (i=0, image=gltextures ; i<numgltextures ; i++, image++)
  318.     {
  319.         if (image->texnum <= 0)
  320.             continue;
  321.         texels += image->upload_width*image->upload_height;
  322.         switch (image->type)
  323.         {
  324.         case it_skin:
  325.             Com_Printf ("M");
  326.             break;
  327.         case it_sprite:
  328.             Com_Printf ("S");
  329.             break;
  330.         case it_wall:
  331.             Com_Printf ("W");
  332.             break;
  333.         case it_pic:
  334.             Com_Printf ("P");
  335.             break;
  336.         default:
  337.             Com_Printf (" ");
  338.             break;
  339.         }
  340.  
  341.         Com_Printf (" %3i %3i %s: %s\n",
  342.             image->upload_width, image->upload_height, palstrings[image->paletted], image->name);
  343.     }
  344.     Com_Printf ("Total texel count (not counting mipmaps): %i\n", texels);
  345. }
  346.  
  347.  
  348. /*
  349. =============================================================================
  350.  
  351.   scrap allocation
  352.  
  353.   Allocate all the little status bar obejcts into a single texture
  354.   to crutch up inefficient hardware / drivers
  355.  
  356. =============================================================================
  357. */
  358.  
  359. #define    MAX_SCRAPS        1
  360. #define    BLOCK_WIDTH        256
  361. #define    BLOCK_HEIGHT    256
  362.  
  363. int            scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
  364. byte        scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT];
  365. qboolean    scrap_dirty;
  366.  
  367. // returns a texture number and the position inside it
  368. int Scrap_AllocBlock (int w, int h, int *x, int *y)
  369. {
  370.     int        i, j;
  371.     int        best, best2;
  372.     int        texnum;
  373.  
  374.     for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
  375.     {
  376.         best = BLOCK_HEIGHT;
  377.  
  378.         for (i=0 ; i<BLOCK_WIDTH-w ; i++)
  379.         {
  380.             best2 = 0;
  381.  
  382.             for (j=0 ; j<w ; j++)
  383.             {
  384.                 if (scrap_allocated[texnum][i+j] >= best)
  385.                     break;
  386.                 if (scrap_allocated[texnum][i+j] > best2)
  387.                     best2 = scrap_allocated[texnum][i+j];
  388.             }
  389.             if (j == w)
  390.             {    // this is a valid spot
  391.                 *x = i;
  392.                 *y = best = best2;
  393.             }
  394.         }
  395.  
  396.         if (best + h > BLOCK_HEIGHT)
  397.             continue;
  398.  
  399.         for (i=0 ; i<w ; i++)
  400.             scrap_allocated[texnum][*x + i] = best + h;
  401.  
  402.         return texnum;
  403.     }
  404.  
  405.     return -1;
  406. //    Sys_Error ("Scrap_AllocBlock: full");
  407. }
  408.  
  409. int    scrap_uploads;
  410.  
  411. void Scrap_Upload (void)
  412. {
  413.     scrap_uploads++;
  414.     GL_Bind(TEXNUM_SCRAPS);
  415.     GL_Upload8 (scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, false );
  416.     scrap_dirty = false;
  417. }
  418.  
  419. /*
  420. =================================================================
  421.  
  422. PCX LOADING
  423.  
  424. =================================================================
  425. */
  426.  
  427.  
  428. /*
  429. ==============
  430. LoadPCX
  431. ==============
  432. */
  433. void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
  434. {
  435.     byte    *raw;
  436.     pcx_t    *pcx;
  437.     int        x, y;
  438.     int        len;
  439.     int        dataByte, runLength;
  440.     byte    *out, *pix;
  441.  
  442.     *pic = NULL;
  443.     *palette = NULL;
  444.  
  445.     //
  446.     // load the file
  447.     //
  448.     len = FS_LoadFile (filename, (void **)&raw);
  449.     if (!raw)
  450.     {
  451.         Com_DPrintf ("Bad pcx file %s\n", filename);
  452.         return;
  453.     }
  454.  
  455.     //
  456.     // parse the PCX file
  457.     //
  458.     pcx = (pcx_t *)raw;
  459.  
  460.     pcx->xmin = LittleShort(pcx->xmin);
  461.     pcx->ymin = LittleShort(pcx->ymin);
  462.     pcx->xmax = LittleShort(pcx->xmax);
  463.     pcx->ymax = LittleShort(pcx->ymax);
  464.     pcx->hres = LittleShort(pcx->hres);
  465.     pcx->vres = LittleShort(pcx->vres);
  466.     pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
  467.     pcx->palette_type = LittleShort(pcx->palette_type);
  468.  
  469.     raw = &pcx->data;
  470.  
  471.     if (pcx->manufacturer != 0x0a
  472.         || pcx->version != 5
  473.         || pcx->encoding != 1
  474.         || pcx->bits_per_pixel != 8
  475.         || pcx->xmax >= 1024
  476.         || pcx->ymax >= 512)
  477.     {
  478.         Com_Printf ("Bad pcx file %s\n", filename);
  479.         FS_FreeFile (pcx);
  480.         return;
  481.     }
  482.  
  483.     out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
  484.  
  485.     *pic = out;
  486.  
  487.     pix = out;
  488.  
  489.     if (palette)
  490.     {
  491.         *palette = malloc(768);
  492.         memcpy (*palette, (byte *)pcx + len - 768, 768);
  493.     }
  494.  
  495.     if (width)
  496.         *width = pcx->xmax+1;
  497.     if (height)
  498.         *height = pcx->ymax+1;
  499.  
  500.     for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
  501.     {
  502.         for (x=0 ; x<=pcx->xmax ; )
  503.         {
  504.             dataByte = *raw++;
  505.  
  506.             if ((dataByte & 0xC0) == 0xC0)
  507.             {
  508.                 runLength = dataByte & 0x3F;
  509.                 dataByte = *raw++;
  510.             }
  511.             else
  512.                 runLength = 1;
  513.  
  514.             while (runLength-- > 0)
  515.                 pix[x++] = dataByte;
  516.         }
  517.  
  518.     }
  519.  
  520.     if ( raw - (byte *)pcx > len)
  521.     {
  522.         Com_DPrintf ("PCX file %s was malformed", filename);
  523.         free (*pic);
  524.         *pic = NULL;
  525.     }
  526.  
  527.     FS_FreeFile (pcx);
  528. }
  529.  
  530. /*
  531. =========================================================
  532.  
  533. TARGA LOADING
  534.  
  535. =========================================================
  536. */
  537.  
  538. typedef struct _TargaHeader {
  539.     unsigned char     id_length, colormap_type, image_type;
  540.     unsigned short    colormap_index, colormap_length;
  541.     unsigned char    colormap_size;
  542.     unsigned short    x_origin, y_origin, width, height;
  543.     unsigned char    pixel_size, attributes;
  544. } TargaHeader;
  545.  
  546.  
  547. /*
  548. =============
  549. LoadTGA
  550. =============
  551. */
  552. void LoadTGA (char *name, byte **pic, int *width, int *height)
  553. {
  554.     int        columns, rows, numPixels;
  555.     byte    *pixbuf;
  556.     int        row, column;
  557.     byte    *buf_p;
  558.     byte    *buffer;
  559.     int        length;
  560.     TargaHeader        targa_header;
  561.     byte            *targa_rgba;
  562.     byte tmp[2];
  563.  
  564.     *pic = NULL;
  565.  
  566.     //
  567.     // load the file
  568.     //
  569.     length = FS_LoadFile (name, (void **)&buffer);
  570.     if (!buffer)
  571.     {
  572.         Com_DPrintf ("Bad tga file %s\n", name);
  573.         return;
  574.     }
  575.  
  576.     buf_p = buffer;
  577.  
  578.     targa_header.id_length = *buf_p++;
  579.     targa_header.colormap_type = *buf_p++;
  580.     targa_header.image_type = *buf_p++;
  581.     
  582.     tmp[0] = buf_p[0];
  583.     tmp[1] = buf_p[1];
  584.     targa_header.colormap_index = LittleShort ( *((short *)tmp) );
  585.     buf_p+=2;
  586.     tmp[0] = buf_p[0];
  587.     tmp[1] = buf_p[1];
  588.     targa_header.colormap_length = LittleShort ( *((short *)tmp) );
  589.     buf_p+=2;
  590.     targa_header.colormap_size = *buf_p++;
  591.     targa_header.x_origin = LittleShort ( *((short *)buf_p) );
  592.     buf_p+=2;
  593.     targa_header.y_origin = LittleShort ( *((short *)buf_p) );
  594.     buf_p+=2;
  595.     targa_header.width = LittleShort ( *((short *)buf_p) );
  596.     buf_p+=2;
  597.     targa_header.height = LittleShort ( *((short *)buf_p) );
  598.     buf_p+=2;
  599.     targa_header.pixel_size = *buf_p++;
  600.     targa_header.attributes = *buf_p++;
  601.  
  602.     if (targa_header.image_type!=2 
  603.         && targa_header.image_type!=10) 
  604.         Com_Error (ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n");
  605.  
  606.     if (targa_header.colormap_type !=0 
  607.         || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
  608.         Com_Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  609.  
  610.     columns = targa_header.width;
  611.     rows = targa_header.height;
  612.     numPixels = columns * rows;
  613.  
  614.     if (width)
  615.         *width = columns;
  616.     if (height)
  617.         *height = rows;
  618.  
  619.     targa_rgba = malloc (numPixels*4);
  620.     *pic = targa_rgba;
  621.  
  622.     if (targa_header.id_length != 0)
  623.         buf_p += targa_header.id_length;  // skip TARGA image comment
  624.     
  625.     if (targa_header.image_type==2) {  // Uncompressed, RGB images
  626.         for(row=rows-1; row>=0; row--) {
  627.             pixbuf = targa_rgba + row*columns*4;
  628.             for(column=0; column<columns; column++) {
  629.                 unsigned char red,green,blue,alphabyte;
  630.                 switch (targa_header.pixel_size) {
  631.                     case 24:
  632.                             
  633.                             blue = *buf_p++;
  634.                             green = *buf_p++;
  635.                             red = *buf_p++;
  636.                             *pixbuf++ = red;
  637.                             *pixbuf++ = green;
  638.                             *pixbuf++ = blue;
  639.                             *pixbuf++ = 255;
  640.                             break;
  641.                     case 32:
  642.                             blue = *buf_p++;
  643.                             green = *buf_p++;
  644.                             red = *buf_p++;
  645.                             alphabyte = *buf_p++;
  646.                             *pixbuf++ = red;
  647.                             *pixbuf++ = green;
  648.                             *pixbuf++ = blue;
  649.                             *pixbuf++ = alphabyte;
  650.                             break;
  651.                 }
  652.             }
  653.         }
  654.     }
  655.     else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  656.         unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  657.         for(row=rows-1; row>=0; row--) {
  658.             pixbuf = targa_rgba + row*columns*4;
  659.             for(column=0; column<columns; ) {
  660.                 packetHeader= *buf_p++;
  661.                 packetSize = 1 + (packetHeader & 0x7f);
  662.                 if (packetHeader & 0x80) {        // run-length packet
  663.                     switch (targa_header.pixel_size) {
  664.                         case 24:
  665.                                 blue = *buf_p++;
  666.                                 green = *buf_p++;
  667.                                 red = *buf_p++;
  668.                                 alphabyte = 255;
  669.                                 break;
  670.                         case 32:
  671.                                 blue = *buf_p++;
  672.                                 green = *buf_p++;
  673.                                 red = *buf_p++;
  674.                                 alphabyte = *buf_p++;
  675.                                 break;
  676.                     }
  677.     
  678.                     for(j=0;j<packetSize;j++) {
  679.                         *pixbuf++=red;
  680.                         *pixbuf++=green;
  681.                         *pixbuf++=blue;
  682.                         *pixbuf++=alphabyte;
  683.                         column++;
  684.                         if (column==columns) { // run spans across rows
  685.                             column=0;
  686.                             if (row>0)
  687.                                 row--;
  688.                             else
  689.                                 goto breakOut;
  690.                             pixbuf = targa_rgba + row*columns*4;
  691.                         }
  692.                     }
  693.                 }
  694.                 else {                            // non run-length packet
  695.                     for(j=0;j<packetSize;j++) {
  696.                         switch (targa_header.pixel_size) {
  697.                             case 24:
  698.                                     blue = *buf_p++;
  699.                                     green = *buf_p++;
  700.                                     red = *buf_p++;
  701.                                     *pixbuf++ = red;
  702.                                     *pixbuf++ = green;
  703.                                     *pixbuf++ = blue;
  704.                                     *pixbuf++ = 255;
  705.                                     break;
  706.                             case 32:
  707.                                     blue = *buf_p++;
  708.                                     green = *buf_p++;
  709.                                     red = *buf_p++;
  710.                                     alphabyte = *buf_p++;
  711.                                     *pixbuf++ = red;
  712.                                     *pixbuf++ = green;
  713.                                     *pixbuf++ = blue;
  714.                                     *pixbuf++ = alphabyte;
  715.                                     break;
  716.                         }
  717.                         column++;
  718.                         if (column==columns) { // pixel packet run spans across rows
  719.                             column=0;
  720.                             if (row>0)
  721.                                 row--;
  722.                             else
  723.                                 goto breakOut;
  724.                             pixbuf = targa_rgba + row*columns*4;
  725.                         }                        
  726.                     }
  727.                 }
  728.             }
  729.             breakOut:;
  730.         }
  731.     }
  732.  
  733.     FS_FreeFile (buffer);
  734. }
  735.  
  736.  
  737. /*
  738. ====================================================================
  739.  
  740. IMAGE FLOOD FILLING
  741.  
  742. ====================================================================
  743. */
  744.  
  745.  
  746. /*
  747. =================
  748. Mod_FloodFillSkin
  749.  
  750. Fill background pixels so mipmapping doesn't have haloes
  751. =================
  752. */
  753.  
  754. typedef struct
  755. {
  756.     short        x, y;
  757. } floodfill_t;
  758.  
  759. // must be a power of 2
  760. #define FLOODFILL_FIFO_SIZE 0x1000
  761. #define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1)
  762.  
  763. #define FLOODFILL_STEP( off, dx, dy ) \
  764. { \
  765.     if (pos[off] == fillcolor) \
  766.     { \
  767.         pos[off] = 255; \
  768.         fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \
  769.         inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
  770.     } \
  771.     else if (pos[off] != 255) fdc = pos[off]; \
  772. }
  773.  
  774. void R_FloodFillSkin( byte *skin, int skinwidth, int skinheight )
  775. {
  776.     byte                fillcolor = *skin; // assume this is the pixel to fill
  777.     floodfill_t            fifo[FLOODFILL_FIFO_SIZE];
  778.     int                    inpt = 0, outpt = 0;
  779.     int                    filledcolor = -1;
  780.     int                    i;
  781.  
  782.     if (filledcolor == -1)
  783.     {
  784.         filledcolor = 0;
  785.         // attempt to find opaque black
  786.         for (i = 0; i < 256; ++i)
  787.             if (d_8to24table[i] == (255 << 0)) // alpha 1.0
  788.             {
  789.                 filledcolor = i;
  790.                 break;
  791.             }
  792.     }
  793.  
  794.     // can't fill to filled color or to transparent color (used as visited marker)
  795.     if ((fillcolor == filledcolor) || (fillcolor == 255))
  796.     {
  797.         //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor );
  798.         return;
  799.     }
  800.  
  801.     fifo[inpt].x = 0, fifo[inpt].y = 0;
  802.     inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
  803.  
  804.     while (outpt != inpt)
  805.     {
  806.         int            x = fifo[outpt].x, y = fifo[outpt].y;
  807.         int            fdc = filledcolor;
  808.         byte        *pos = &skin[x + skinwidth * y];
  809.  
  810.         outpt = (outpt + 1) & FLOODFILL_FIFO_MASK;
  811.  
  812.         if (x > 0)                FLOODFILL_STEP( -1, -1, 0 );
  813.         if (x < skinwidth - 1)    FLOODFILL_STEP( 1, 1, 0 );
  814.         if (y > 0)                FLOODFILL_STEP( -skinwidth, 0, -1 );
  815.         if (y < skinheight - 1)    FLOODFILL_STEP( skinwidth, 0, 1 );
  816.         skin[x + skinwidth * y] = fdc;
  817.     }
  818. }
  819.  
  820. //=======================================================
  821.  
  822.  
  823. /*
  824. ================
  825. GL_ResampleTexture
  826. ================
  827. */
  828. void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight)
  829. {
  830.     int        i, j;
  831.     unsigned    *inrow, *inrow2;
  832.     unsigned    frac, fracstep;
  833.     unsigned    p1[1024], p2[1024];
  834.     byte        *pix1, *pix2, *pix3, *pix4;
  835.  
  836.     fracstep = inwidth*0x10000/outwidth;
  837.  
  838.     frac = fracstep>>2;
  839.     for (i=0 ; i<outwidth ; i++)
  840.     {
  841.         p1[i] = 4*(frac>>16);
  842.         frac += fracstep;
  843.     }
  844.     frac = 3*(fracstep>>2);
  845.     for (i=0 ; i<outwidth ; i++)
  846.     {
  847.         p2[i] = 4*(frac>>16);
  848.         frac += fracstep;
  849.     }
  850.  
  851.     for (i=0 ; i<outheight ; i++, out += outwidth)
  852.     {
  853.         inrow = in + inwidth*(int)((i+0.25)*inheight/outheight);
  854.         inrow2 = in + inwidth*(int)((i+0.75)*inheight/outheight);
  855.         frac = fracstep >> 1;
  856.         for (j=0 ; j<outwidth ; j++)
  857.         {
  858.             pix1 = (byte *)inrow + p1[j];
  859.             pix2 = (byte *)inrow + p2[j];
  860.             pix3 = (byte *)inrow2 + p1[j];
  861.             pix4 = (byte *)inrow2 + p2[j];
  862.             ((byte *)(out+j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
  863.             ((byte *)(out+j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
  864.             ((byte *)(out+j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
  865.             ((byte *)(out+j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2;
  866.         }
  867.     }
  868. }
  869.  
  870. /*
  871. ================
  872. GL_LightScaleTexture
  873.  
  874. Scale up the pixel values in a texture to increase the
  875. lighting range
  876. ================
  877. */
  878. void GL_LightScaleTexture (unsigned *in, int inwidth, int inheight, qboolean only_gamma )
  879. {
  880.     if ( only_gamma )
  881.     {
  882.         int        i, c;
  883.         byte    *p;
  884.  
  885.         p = (byte *)in;
  886.  
  887.         c = inwidth*inheight;
  888.         for (i=0 ; i<c ; i++, p+=4)
  889.         {
  890.             p[0] = gammatable[p[0]];
  891.             p[1] = gammatable[p[1]];
  892.             p[2] = gammatable[p[2]];
  893.         }
  894.     }
  895.     else
  896.     {
  897.         int        i, c;
  898.         byte    *p;
  899.  
  900.         p = (byte *)in;
  901.  
  902.         c = inwidth*inheight;
  903.         for (i=0 ; i<c ; i++, p+=4)
  904.         {
  905.             p[0] = gammatable[intensitytable[p[0]]];
  906.             p[1] = gammatable[intensitytable[p[1]]];
  907.             p[2] = gammatable[intensitytable[p[2]]];
  908.         }
  909.     }
  910. }
  911.  
  912. /*
  913. ================
  914. GL_MipMap
  915.  
  916. Operates in place, quartering the size of the texture
  917. ================
  918. */
  919. void GL_MipMap (byte *in, int width, int height)
  920. {
  921.     int        i, j;
  922.     byte    *out;
  923.  
  924.     width <<=2;
  925.     height >>= 1;
  926.     out = in;
  927.     for (i=0 ; i<height ; i++, in+=width)
  928.     {
  929.         for (j=0 ; j<width ; j+=8, out+=4, in+=8)
  930.         {
  931.             out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
  932.             out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
  933.             out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
  934.             out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
  935.         }
  936.     }
  937. }
  938.  
  939. #ifdef EXTREME
  940. int        upload_width, upload_height;
  941. qboolean uploaded_paletted;
  942. // Fixed 256x256 texture size limitation - MrG
  943. qboolean GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap)
  944. {    int        samples;
  945.     unsigned     *scaled;
  946.     int        scaled_width, scaled_height;
  947.     int        i, c;
  948.     byte        *scan;
  949.     int comp;
  950.  
  951.     uploaded_paletted = false;    // scan the texture for any non-255 alpha 
  952.     c = width*height; 
  953.     scan = ((byte *)data) + 3; 
  954.     samples = gl_solid_format; 
  955.     for (i=0 ; i<c ; i++, scan += 4) 
  956.     { 
  957.         if ( *scan != 255 ) 
  958.         { 
  959.             samples = gl_alpha_format; 
  960.             break; 
  961.         } 
  962.     } 
  963.     comp = (samples == gl_solid_format) ? gl_tex_solid_format : gl_tex_alpha_format; 
  964.  
  965.     { 
  966.         int powers_of_two[] = {16,32,64,128,256,512,1024,2048,4096}; 
  967.         int max_size; 
  968.         int i; 
  969.         qglGetIntegerv(GL_MAX_TEXTURE_SIZE,&max_size); 
  970.         scaled_width = scaled_height = 0; 
  971.  
  972.         for (i=0; i<8; i++) 
  973.         { 
  974.             if (width >= powers_of_two[i] && width < powers_of_two[i+1]) { 
  975.                 if (width > ((powers_of_two[i] + powers_of_two[i+1])/2)) 
  976.                     scaled_width = powers_of_two[i+1]; 
  977.                 else 
  978.                     scaled_width = powers_of_two[i]; 
  979.             } else if (width == powers_of_two[i+1]) { 
  980.                 scaled_width = powers_of_two[i+1]; 
  981.             } 
  982.             if (scaled_width && scaled_height) 
  983.                 break; 
  984.             if (height >= powers_of_two[i] && height < powers_of_two[i+1]) { 
  985.                 if (height > ((powers_of_two[i] + powers_of_two[i+1])/2)) 
  986.                     scaled_height = powers_of_two[i+1]; 
  987.                 else 
  988.                     scaled_height = powers_of_two[i]; 
  989.             } else if (height == powers_of_two[i+1]) { 
  990.                 scaled_height = powers_of_two[i+1]; 
  991.             }            if (scaled_width && scaled_height) 
  992.                 break; 
  993.         } 
  994.  
  995.         if (scaled_width > max_size) 
  996.             scaled_width = max_size; 
  997.         if (scaled_height > max_size) 
  998.             scaled_height = max_size; 
  999.     } 
  1000.  
  1001.     if (scaled_width != width || scaled_height != height) { 
  1002.         scaled=malloc((scaled_width * scaled_height) * 4); 
  1003.         GL_ResampleTexture(data,width,height,scaled,scaled_width,scaled_height); 
  1004.     } else { 
  1005.         scaled_width=width; 
  1006.         scaled_height=height; 
  1007.         scaled=data; 
  1008.     } 
  1009.  
  1010.     if (mipmap) { 
  1011.         GL_LightScaleTexture (scaled, scaled_width, scaled_height, !mipmap); 
  1012.         gluBuild2DMipmaps (GL_TEXTURE_2D, samples, scaled_width, scaled_height, GL_RGBA, GL_UNSIGNED_BYTE, scaled); 
  1013.     } else {  
  1014.         GL_LightScaleTexture (scaled, scaled_width, scaled_height, !mipmap ); 
  1015.         qglTexImage2D (GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); 
  1016.     } 
  1017.     if (scaled_width != width || scaled_height != height) 
  1018.         free(scaled); 
  1019.  
  1020.     upload_width =scaled_width; 
  1021.     upload_height = scaled_height; 
  1022.     if (mipmap) 
  1023.     { 
  1024.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); 
  1025.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); 
  1026.     } 
  1027.     else 
  1028.     {         
  1029.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); 
  1030.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); 
  1031.     }     
  1032.     return (samples == gl_alpha_format); 
  1033. #else
  1034. /*
  1035. ===============
  1036. GL_Upload32
  1037.  
  1038. Returns has_alpha
  1039. ===============
  1040. */
  1041. void GL_BuildPalettedTexture( unsigned char *paletted_texture, unsigned char *scaled, int scaled_width, int scaled_height )
  1042. {
  1043.     int i;
  1044.  
  1045.     for ( i = 0; i < scaled_width * scaled_height; i++ )
  1046.     {
  1047.         unsigned int r, g, b, c;
  1048.  
  1049.         r = ( scaled[0] >> 3 ) & 31;
  1050.         g = ( scaled[1] >> 2 ) & 63;
  1051.         b = ( scaled[2] >> 3 ) & 31;
  1052.  
  1053.         c = r | ( g << 5 ) | ( b << 11 );
  1054.  
  1055.         paletted_texture[i] = gl_state.d_16to8table[c];
  1056.  
  1057.         scaled += 4;
  1058.     }
  1059. }
  1060.  
  1061. int        upload_width, upload_height;
  1062. qboolean uploaded_paletted;
  1063.  
  1064. qboolean GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap)
  1065. {
  1066.     int            samples;
  1067.     unsigned    scaled[256*256];
  1068.     unsigned char paletted_texture[256*256];
  1069.     int            scaled_width, scaled_height;
  1070.     int            i, c;
  1071.     byte        *scan;
  1072.     int comp;
  1073.  
  1074.     uploaded_paletted = false;
  1075.  
  1076.     for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  1077.         ;
  1078.     if (gl_round_down->value && scaled_width > width && mipmap)
  1079.         scaled_width >>= 1;
  1080.     for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  1081.         ;
  1082.     if (gl_round_down->value && scaled_height > height && mipmap)
  1083.         scaled_height >>= 1;
  1084.  
  1085.     // let people sample down the world textures for speed
  1086.     if (mipmap)
  1087.     {
  1088.         scaled_width >>= (int)gl_picmip->value;
  1089.         scaled_height >>= (int)gl_picmip->value;
  1090.     }
  1091.  
  1092.     // don't ever bother with >256 textures
  1093.     if (scaled_width > 256)
  1094.         scaled_width = 256;
  1095.     if (scaled_height > 256)
  1096.         scaled_height = 256;
  1097.  
  1098.     if (scaled_width < 1)
  1099.         scaled_width = 1;
  1100.     if (scaled_height < 1)
  1101.         scaled_height = 1;
  1102.  
  1103.     upload_width = scaled_width;
  1104.     upload_height = scaled_height;
  1105.  
  1106.     if (scaled_width * scaled_height > sizeof(scaled)/4)
  1107.         Com_Error (ERR_DROP, "GL_Upload32: too big");
  1108.  
  1109.     // scan the texture for any non-255 alpha
  1110.     c = width*height;
  1111.     scan = ((byte *)data) + 3;
  1112.     samples = gl_solid_format;
  1113.     for (i=0 ; i<c ; i++, scan += 4)
  1114.     {
  1115.         if ( *scan != 255 )
  1116.         {
  1117.             samples = gl_alpha_format;
  1118.             break;
  1119.         }
  1120.     }
  1121.  
  1122.     if (samples == gl_solid_format)
  1123.         comp = gl_tex_solid_format;
  1124.     else if (samples == gl_alpha_format)
  1125.         comp = gl_tex_alpha_format;
  1126.     else {
  1127.         Com_Printf (
  1128.                "Unknown number of texture components %i\n",
  1129.                samples);
  1130.         comp = samples;
  1131.     }
  1132.  
  1133.     if (scaled_width == width && scaled_height == height)
  1134.     {
  1135.         if (!mipmap)
  1136.         {
  1137.             if ( qglColorTableEXT && gl_ext_palettedtexture->value && samples == gl_solid_format )
  1138.             {
  1139.                 uploaded_paletted = true;
  1140.                 GL_BuildPalettedTexture( paletted_texture, ( unsigned char * ) data, scaled_width, scaled_height );
  1141.                 qglTexImage2D( GL_TEXTURE_2D,
  1142.                               0,
  1143.                               GL_COLOR_INDEX8_EXT,
  1144.                               scaled_width,
  1145.                               scaled_height,
  1146.                               0,
  1147.                               GL_COLOR_INDEX,
  1148.                               GL_UNSIGNED_BYTE,
  1149.                               paletted_texture );
  1150.             }
  1151.             else
  1152.             {
  1153.                 qglTexImage2D (GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  1154.             }
  1155.             goto done;
  1156.         }
  1157.         memcpy (scaled, data, width*height*4);
  1158.     }
  1159.     else
  1160.         GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
  1161.  
  1162.     GL_LightScaleTexture (scaled, scaled_width, scaled_height, !mipmap );
  1163.  
  1164.     if ( qglColorTableEXT && gl_ext_palettedtexture->value && ( samples == gl_solid_format ) )
  1165.     {
  1166.         uploaded_paletted = true;
  1167.         GL_BuildPalettedTexture( paletted_texture, ( unsigned char * ) scaled, scaled_width, scaled_height );
  1168.         qglTexImage2D( GL_TEXTURE_2D,
  1169.                       0,
  1170.                       GL_COLOR_INDEX8_EXT,
  1171.                       scaled_width,
  1172.                       scaled_height,
  1173.                       0,
  1174.                       GL_COLOR_INDEX,
  1175.                       GL_UNSIGNED_BYTE,
  1176.                       paletted_texture );
  1177.     }
  1178.     else
  1179.     {
  1180.         qglTexImage2D( GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled );
  1181.     }
  1182.  
  1183.     if (mipmap)
  1184.     {
  1185.         int        miplevel;
  1186.  
  1187.         miplevel = 0;
  1188.         while (scaled_width > 1 || scaled_height > 1)
  1189.         {
  1190.             GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
  1191.             scaled_width >>= 1;
  1192.             scaled_height >>= 1;
  1193.             if (scaled_width < 1)
  1194.                 scaled_width = 1;
  1195.             if (scaled_height < 1)
  1196.                 scaled_height = 1;
  1197.             miplevel++;
  1198.             if ( qglColorTableEXT && gl_ext_palettedtexture->value && samples == gl_solid_format )
  1199.             {
  1200.                 uploaded_paletted = true;
  1201.                 GL_BuildPalettedTexture( paletted_texture, ( unsigned char * ) scaled, scaled_width, scaled_height );
  1202.                 qglTexImage2D( GL_TEXTURE_2D,
  1203.                               miplevel,
  1204.                               GL_COLOR_INDEX8_EXT,
  1205.                               scaled_width,
  1206.                               scaled_height,
  1207.                               0,
  1208.                               GL_COLOR_INDEX,
  1209.                               GL_UNSIGNED_BYTE,
  1210.                               paletted_texture );
  1211.             }
  1212.             else
  1213.             {
  1214.                 qglTexImage2D (GL_TEXTURE_2D, miplevel, comp, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1215.             }
  1216.         }
  1217.     }
  1218. done: ;
  1219.  
  1220.     if (mipmap)
  1221.     {
  1222.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  1223.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1224.     }
  1225.     else
  1226.     {
  1227.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  1228.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1229.     }
  1230.  
  1231.     return (samples == gl_alpha_format);
  1232. }
  1233. #endif
  1234. /*
  1235. ===============
  1236. GL_Upload8
  1237.  
  1238. Returns has_alpha
  1239. ===============
  1240. */
  1241. qboolean GL_Upload8 (byte *data, int width, int height,  qboolean mipmap, qboolean is_sky )
  1242. {
  1243.     unsigned    trans[512*256];
  1244.     int            i, s;
  1245.     int            p;
  1246.  
  1247.     s = width*height;
  1248.  
  1249.     if (s > sizeof(trans)/4)
  1250.         Com_Error (ERR_DROP, "GL_Upload8: too large");
  1251.  
  1252.     if ( qglColorTableEXT && 
  1253.          gl_ext_palettedtexture->value && 
  1254.          is_sky )
  1255.     {
  1256.         qglTexImage2D( GL_TEXTURE_2D,
  1257.                       0,
  1258.                       GL_COLOR_INDEX8_EXT,
  1259.                       width,
  1260.                       height,
  1261.                       0,
  1262.                       GL_COLOR_INDEX,
  1263.                       GL_UNSIGNED_BYTE,
  1264.                       data );
  1265.  
  1266.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  1267.         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1268.  
  1269.         return false;
  1270.     }
  1271.     else
  1272.     {
  1273.         for (i=0 ; i<s ; i++)
  1274.         {
  1275.             p = data[i];
  1276.             trans[i] = d_8to24table[p];
  1277.  
  1278.             if (p == 255)
  1279.             {    // transparent, so scan around for another color
  1280.                 // to avoid alpha fringes
  1281.                 // FIXME: do a full flood fill so mips work...
  1282.                 if (i > width && data[i-width] != 255)
  1283.                     p = data[i-width];
  1284.                 else if (i < s-width && data[i+width] != 255)
  1285.                     p = data[i+width];
  1286.                 else if (i > 0 && data[i-1] != 255)
  1287.                     p = data[i-1];
  1288.                 else if (i < s-1 && data[i+1] != 255)
  1289.                     p = data[i+1];
  1290.                 else
  1291.                     p = 0;
  1292.                 // copy rgb components
  1293.                 ((byte *)&trans[i])[0] = ((byte *)&d_8to24table[p])[0];
  1294.                 ((byte *)&trans[i])[1] = ((byte *)&d_8to24table[p])[1];
  1295.                 ((byte *)&trans[i])[2] = ((byte *)&d_8to24table[p])[2];
  1296.             }
  1297.         }
  1298.  
  1299.         return GL_Upload32 (trans, width, height, mipmap);
  1300.     }
  1301. }
  1302.  
  1303.  
  1304. /*
  1305. ================
  1306. GL_LoadPic
  1307.  
  1308. This is also used as an entry point for the generated r_notexture
  1309. ================
  1310. */
  1311. image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type, int bits)
  1312. {
  1313.     image_t        *image;
  1314.     int            i;
  1315.  
  1316.     // find a free image_t
  1317.     for (i=0, image=gltextures ; i<numgltextures ; i++,image++)
  1318.     {
  1319.         if (!image->texnum)
  1320.             break;
  1321.     }
  1322.     if (i == numgltextures)
  1323.     {
  1324.         if (numgltextures == MAX_GLTEXTURES)
  1325.             Com_Error (ERR_DROP, "MAX_GLTEXTURES");
  1326.         numgltextures++;
  1327.     }
  1328.     image = &gltextures[i];
  1329.  
  1330.     if (strlen(name) >= sizeof(image->name))
  1331.         Com_Error (ERR_DROP, "Draw_LoadPic: \"%s\" is too long", name);
  1332.     strcpy (image->name, name);
  1333.     image->registration_sequence = registration_sequence;
  1334.  
  1335.     image->width = width;
  1336.     image->height = height;
  1337.     image->type = type;
  1338.  
  1339.     if (type == it_skin && bits == 8)
  1340.         R_FloodFillSkin(pic, width, height);
  1341.  
  1342.     // load little pics into the scrap
  1343.     if (image->type == it_pic && bits == 8
  1344.         && image->width < 64 && image->height < 64)
  1345.     {
  1346.         int        x, y;
  1347.         int        i, j, k;
  1348.         int        texnum;
  1349.  
  1350.         texnum = Scrap_AllocBlock (image->width, image->height, &x, &y);
  1351.         if (texnum == -1)
  1352.             goto nonscrap;
  1353.         scrap_dirty = true;
  1354.  
  1355.         // copy the texels into the scrap block
  1356.         k = 0;
  1357.         for (i=0 ; i<image->height ; i++)
  1358.             for (j=0 ; j<image->width ; j++, k++)
  1359.                 scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = pic[k];
  1360.         image->texnum = TEXNUM_SCRAPS + texnum;
  1361.         image->scrap = true;
  1362.         image->has_alpha = true;
  1363.         image->sl = (x+0.01)/(float)BLOCK_WIDTH;
  1364.         image->sh = (x+image->width-0.01)/(float)BLOCK_WIDTH;
  1365.         image->tl = (y+0.01)/(float)BLOCK_WIDTH;
  1366.         image->th = (y+image->height-0.01)/(float)BLOCK_WIDTH;
  1367.     }
  1368.     else
  1369.     {
  1370. nonscrap:
  1371.         image->scrap = false;
  1372.         image->texnum = TEXNUM_IMAGES + (image - gltextures);
  1373.         GL_Bind(image->texnum);
  1374.         if (bits == 8)
  1375.             image->has_alpha = GL_Upload8 (pic, width, height, (image->type != it_pic && image->type != it_sky), image->type == it_sky );
  1376.         else
  1377.             image->has_alpha = GL_Upload32 ((unsigned *)pic, width, height, (image->type != it_pic && image->type != it_sky) );
  1378.         image->upload_width = upload_width;        // after power of 2 and scales
  1379.         image->upload_height = upload_height;
  1380.         image->paletted = uploaded_paletted;
  1381.         image->sl = 0;
  1382.         image->sh = 1;
  1383.         image->tl = 0;
  1384.         image->th = 1;
  1385.     }
  1386.  
  1387.     return image;
  1388. }
  1389.  
  1390.  
  1391. /*
  1392. ================
  1393. GL_LoadWal
  1394. ================
  1395. */
  1396. image_t *GL_LoadWal (char *name)
  1397. {
  1398.     miptex_t    *mt;
  1399.     int            width, height, ofs;
  1400.     image_t        *image;
  1401.  
  1402.     FS_LoadFile (name, (void **)&mt);
  1403.     if (!mt)
  1404.     {
  1405.         Com_Printf ("GL_FindImage: can't load %s\n", name);
  1406.         return r_notexture;
  1407.     }
  1408.  
  1409.     width = LittleLong (mt->width);
  1410.     height = LittleLong (mt->height);
  1411.     ofs = LittleLong (mt->offsets[0]);
  1412.  
  1413.     image = GL_LoadPic (name, (byte *)mt + ofs, width, height, it_wall, 8);
  1414.  
  1415.     FS_FreeFile ((void *)mt);
  1416.  
  1417.     return image;
  1418. }
  1419.  
  1420. /*
  1421. ===============
  1422. GL_FindImage
  1423.  
  1424. Finds or loads the given image
  1425. ===============
  1426. */
  1427. image_t    *GL_FindImage (char *name, imagetype_t type)
  1428. {
  1429.     image_t    *image;
  1430.     int        i, len;
  1431.     byte    *pic, *palette;
  1432.     int        width, height;
  1433.     char    shortname[MAX_QPATH];
  1434.  
  1435.     if (!name)
  1436.         return NULL;    //    Com_Error (ERR_DROP, "GL_FindImage: NULL name");
  1437.     len = strlen(name);
  1438.     if (len<5)
  1439.         return NULL;    //    Com_Error (ERR_DROP, "GL_FindImage: bad name: %s", name);
  1440.  
  1441.     // look for it
  1442.     for (i=0, image=gltextures ; i<numgltextures ; i++,image++)
  1443.     {
  1444.         if (!strcmp(name, image->name))
  1445.         {
  1446.             image->registration_sequence = registration_sequence;
  1447.             return image;
  1448.         }
  1449.     }
  1450.  
  1451.     // strip off .pcx, .tga, etc...
  1452.     COM_StripExtension ( name, shortname );
  1453.  
  1454.     //
  1455.     // load the pic from disk
  1456.     //
  1457.     image = NULL;
  1458.     pic = NULL;
  1459.     palette = NULL;
  1460.  
  1461.     // try to load .tga first
  1462.     LoadTGA (va("%s.tga", shortname), &pic, &width, &height);
  1463.     if (pic) 
  1464.     {
  1465.         image = GL_LoadPic (name, pic, width, height, type, 32);
  1466.         goto done;
  1467.     }
  1468.  
  1469.     // then comes .pcx
  1470.     LoadPCX (va("%s.pcx", shortname), &pic, &palette, &width, &height);
  1471.     if (pic) 
  1472.     {
  1473.         image = GL_LoadPic (name, pic, width, height, type, 8);
  1474.         goto done;
  1475.     }
  1476.  
  1477.     // then comes .wal
  1478.     if (type == it_wall)
  1479.         image = GL_LoadWal (va("%s.wal", shortname));
  1480.  
  1481. done:
  1482.     if (pic)
  1483.         free(pic);
  1484.     if (palette)
  1485.         free(palette);
  1486.  
  1487.     return image;
  1488. }
  1489.  
  1490.  
  1491.  
  1492. /*
  1493. ===============
  1494. R_RegisterSkin
  1495. ===============
  1496. */
  1497. struct image_s *R_RegisterSkin (char *name)
  1498. {
  1499.     return GL_FindImage (name, it_skin);
  1500. }
  1501.  
  1502.  
  1503. /*
  1504. ================
  1505. GL_FreeUnusedImages
  1506.  
  1507. Any image that was not touched on this registration sequence
  1508. will be freed.
  1509. ================
  1510. */
  1511. void GL_FreeUnusedImages (void)
  1512. {
  1513.     int        i;
  1514.     image_t    *image;
  1515.  
  1516.     // never free r_notexture or particle texture
  1517.     r_notexture->registration_sequence = registration_sequence;
  1518.     r_particletexture->registration_sequence = registration_sequence;
  1519.     r_shelltexture->registration_sequence = registration_sequence;    // c14 added shell texture
  1520.  
  1521.     for (i=0, image=gltextures ; i<numgltextures ; i++, image++)
  1522.     {
  1523.         if (image->registration_sequence == registration_sequence)
  1524.             continue;        // used this sequence
  1525.         if (!image->registration_sequence)
  1526.             continue;        // free image_t slot
  1527.         if (image->type == it_pic)
  1528.             continue;        // don't free pics
  1529.         // free it
  1530.         qglDeleteTextures (1, &image->texnum);
  1531.         memset (image, 0, sizeof(*image));
  1532.     }
  1533. }
  1534.  
  1535.  
  1536. /*
  1537. ===============
  1538. Draw_GetPalette
  1539. ===============
  1540. */
  1541. int Draw_GetPalette (void)
  1542. {
  1543.     int        i;
  1544.     int        r, g, b;
  1545.     unsigned    v;
  1546.     byte    *pic, *pal;
  1547.     int        width, height;
  1548.  
  1549.     // get the palette
  1550.  
  1551.     LoadPCX ("pics/colormap.pcx", &pic, &pal, &width, &height);
  1552.     if (!pal)
  1553.         Com_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
  1554.  
  1555.     for (i=0 ; i<256 ; i++)
  1556.     {
  1557.         r = pal[i*3+0];
  1558.         g = pal[i*3+1];
  1559.         b = pal[i*3+2];
  1560.         
  1561.         v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
  1562.         d_8to24table[i] = LittleLong(v);
  1563.     }
  1564.  
  1565.     d_8to24table[255] &= LittleLong(0xffffff);    // 255 is transparent
  1566.  
  1567.     free (pic);
  1568.     free (pal);
  1569.  
  1570.     return 0;
  1571. }
  1572.  
  1573.  
  1574. /*
  1575. ===============
  1576. GL_InitImages
  1577. ===============
  1578. */
  1579. void    GL_InitImages (void)
  1580. {
  1581.     int        i, j;
  1582.     float    g = vid_gamma->value;
  1583.  
  1584.     registration_sequence = 1;
  1585.  
  1586.     // init intensity conversions
  1587.     intensity = Cvar_Get ("intensity", "1", 0);
  1588.  
  1589.     if ( intensity->value <= 1 )
  1590.         Cvar_Set( "intensity", "1" );
  1591.  
  1592.     gl_state.inverse_intensity = 1 / intensity->value;
  1593.  
  1594.     Draw_GetPalette ();
  1595.  
  1596.     if ( qglColorTableEXT )
  1597.     {
  1598.         FS_LoadFile( "pics/16to8.dat", &gl_state.d_16to8table );
  1599.         if ( !gl_state.d_16to8table )
  1600.             Sys_Error( ERR_FATAL, "Couldn't load pics/16to8.pcx");
  1601.     }
  1602.  
  1603.     if ( gl_config.renderer & ( GL_RENDERER_VOODOO | GL_RENDERER_VOODOO2 ) )
  1604.     {
  1605.         g = 1.0F;
  1606.     }
  1607.  
  1608.     for ( i = 0; i < 256; i++ )
  1609.     {
  1610.         if ( g == 1 )
  1611.         {
  1612.             gammatable[i] = i;
  1613.         }
  1614.         else
  1615.         {
  1616.             float inf;
  1617.  
  1618.             inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
  1619.             if (inf < 0)
  1620.                 inf = 0;
  1621.             if (inf > 255)
  1622.                 inf = 255;
  1623.             gammatable[i] = inf;
  1624.         }
  1625.     }
  1626.  
  1627.     for (i=0 ; i<256 ; i++)
  1628.     {
  1629.         j = i*intensity->value;
  1630.         if (j > 255)
  1631.             j = 255;
  1632.         intensitytable[i] = j;
  1633.     }
  1634. }
  1635.  
  1636. /*
  1637. ===============
  1638. GL_ShutdownImages
  1639. ===============
  1640. */
  1641. void    GL_ShutdownImages (void)
  1642. {
  1643.     int        i;
  1644.     image_t    *image;
  1645.  
  1646.     for (i=0, image=gltextures ; i<numgltextures ; i++, image++)
  1647.     {
  1648.         if (!image->registration_sequence)
  1649.             continue;        // free image_t slot
  1650.         // free it
  1651.         qglDeleteTextures (1, &image->texnum);
  1652.         memset (image, 0, sizeof(*image));
  1653.     }
  1654. }
  1655.  
  1656.